package com.azr.jesus.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.azr.jesus.common.domain.ResultData;
import com.azr.jesus.common.utils.EasyExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

import com.azr.jesus.service.ISysFileService;
import com.azr.jesus.entity.SysFiles;
import org.springframework.web.multipart.MultipartFile;


/**
 * 文件信息表 前端控制器
 * @author: Xiong
 * @date: 2022-11-20
 */
@RestController
@RequestMapping("/sys-file")
public class SysFileController {

    @Resource
    private ISysFileService sysFileService;

    @Value("${files.upload.path}")
    private String uploadPath;

    private static final String localUrl = "http://localhost:9876/sys-file/download/";

    /**
     * 文件上传接口
     *
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    @ApiOperation(value = "文件上传")
    public String upload(@RequestParam MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String type = FileUtil.extName(originalFilename);
        long size = file.getSize();
        // 先存储到磁盘
        // 定义文件唯一标识
        String uuid = IdUtil.fastSimpleUUID();
        File uploadFilePath = new File(uploadPath + uuid + StrUtil.DOT + type);
        // 判断文件路径是否存在
        if (!uploadFilePath.getParentFile().exists()) {
            uploadFilePath.getParentFile().mkdirs();
        }

        String url;
        // 把获取到的文件存到磁盘
        file.transferTo(uploadFilePath);
        // 获取文件的md5，去重
        String md5 = SecureUtil.md5(uploadFilePath);
        SysFiles one = getFileByMd5(md5);
        if (one != null) {
            url = one.getUrl();
            // 文件存在删除
            uploadFilePath.delete();
        } else {
            url = localUrl + uuid + StrUtil.DOT + type;
        }

        // 存储数据库
        SysFiles sysFile = SysFiles.builder()
                .name(originalFilename).type(type).md5(md5)
                .size(size / 1024).url(url)
                .build();
        sysFileService.save(sysFile);
        return url;
    }

    @GetMapping("/download/{fileUUID}")
    @ApiOperation(value = "下载文件")
    public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
        // 根据文件的唯一标识获取文件
        File uploadFile = new File(uploadPath, fileUUID);
        // 设置输出流的格式
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("Content-Disposition" , "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
        response.setContentType("application/octet-stream");

        // 读取文件的字节流
        os.write(FileUtil.readBytes(uploadFile));
        os.flush();
        os.close();
    }


    @PostMapping
    @ApiOperation(value = "新增")
    public ResultData save(@RequestBody SysFiles sysFile) {
        return ResultData.success(sysFileService.saveOrUpdate(sysFile));
    }

    @DeleteMapping("/{id}")
    @ApiOperation(value = "删除")
    public ResultData delete(@PathVariable Integer id) {
        SysFiles sysFile = sysFileService.getById(id);
        sysFile.setIsDelete(true);
        return ResultData.success(sysFileService.updateById(sysFile));
    }

    @PostMapping(value = "/batchDelete")
    @ApiOperation(value = "批量删除")
    public ResultData batchDelete(@RequestBody List<Integer> ids) {
        QueryWrapper<SysFiles> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", ids);
        List<SysFiles> files = sysFileService.list(queryWrapper);
        for (SysFiles file : files) {
            file.setIsDelete(true);
            sysFileService.updateById(file);
        }
        return ResultData.success();
    }

    @PostMapping("/update")
    @ApiOperation(value = "修改")
    public ResultData update(@RequestBody SysFiles sysFile) {
        return ResultData.success(sysFileService.updateById(sysFile));
    }

    @GetMapping
    @ApiOperation(value = "获取列表")
    public ResultData findAll() {
        return ResultData.success(sysFileService.list());
    }

    @GetMapping("/{id}")
    @ApiOperation(value = "获取一条")
    public ResultData findOne(@PathVariable Integer id) {
        return ResultData.success(sysFileService.getById(id));
    }

    @GetMapping("/page")
    @ApiOperation(value = "分页查询")
    public ResultData findPage(@RequestParam Integer pageNum,
                               @RequestParam Integer pageSize,
                               @RequestParam String name) {
        QueryWrapper<SysFiles> query = new QueryWrapper<>();
        query.eq("is_delete", false);
        query.orderByDesc("id");
        if (StrUtil.isNotBlank(name)) {
            query.like("name",name);
        }
        return ResultData.success(sysFileService.page(new Page<>(pageNum, pageSize), query));
    }

    @GetMapping("/export")
    @ApiOperation(value = "Excel导出")
    public void export(HttpServletResponse response) throws IOException {
        List<SysFiles> sysFileList = sysFileService.list();
        EasyExcelUtil.download(response, sysFileList, "文件信息表");
    }

    /**
     * 根据md5获取文件
     *
     * @param md5
     * @return
     */
    private SysFiles getFileByMd5(String md5) {
        QueryWrapper<SysFiles> query = new QueryWrapper<>();
        query.eq("md5" , md5);
        List<SysFiles> list = sysFileService.list(query);
        return list.size() == 0 ? null : list.get(0);
    }
}

